<?php
/**
 * Author: lee wei
 * Date: 2021/12/10
 */
namespace app\common\exception;

use app\common\JsonResponse;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
use ErrorException;
use Exception;
use InvalidArgumentException;
use ParseError;
//use PDOException;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\ClassNotFoundException;
use think\exception\HttpResponseException;
use think\exception\RouteNotFoundException;
use TypeError;
use app\Common\Coderesponse;

class MyException extends Handle
{
    use JsonResponse;

    public function render($request, Throwable $e): Response
    {
        //如果处于调试模式
        if (env('app_debug')){ //var_dump($e);
            $this->debug = [
                'url' => $request->host().$request->url(),
                'code' => $e->getCode(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'message' => $e->getMessage(),
                'trace' => $e->getTrace(),
            ];
        }
        // 参数验证错误
        if ($e instanceof ValidateException) {
            return $this->buildFailed(Coderesponse::UNPROCESSABLE,$e->getError());
        }

        // 请求404异常 , 不返回错误页面
        if (($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode() == 404)) {
            return $this->buildFailed(Coderesponse::NOT_FOUND,'当前请求资源不存在，请稍后再试!');
        }

        //请求500异常, 不返回错误页面
        //$e instanceof PDOException ||
        if ($e instanceof Exception ||  $e instanceof HttpException || $e instanceof InvalidArgumentException || $e instanceof ErrorException || $e instanceof ParseError || $e instanceof TypeError)  {

            $this->reportException($request, $e);
            return $this->buildFailed(Coderesponse::SERVICE_ERROR,'系统异常，请稍后再试');
        }

        //其他错误
        $this->reportException($request, $e);
        return $this->buildFailed(Coderesponse::ERROR,"应用发生错误");
    }

    //记录exception到日志
    private function reportException($request, Throwable $e):void {
        $errorStr = "url:".$request->host().$request->url()."\n";
        $errorStr .= "code:".$e->getCode()."\n";
        //$errorStr .= "file:".$e->getFile()."\n";
        //$errorStr .= "line:".$e->getLine()."\n";
        $errorStr .= "message:".$e->getMessage()."\n";
        //$errorStr .=  $e->getTraceAsString();

        trace($errorStr, 'error');
    }

}